/* 
 * File:   DirCommand.cpp
 * Author: Bram
 * 
 * syntax: (zonder []!)
 * [dir:"PATH"] = alle files in de huidige dir, zonder subdirs
 * [dir:"c:\test\" "1"] OF [dir:"c:\test\" "FULL"] = alle files in de huidige dir, MET subdirs
 * [dir:"test" "" "1"] OF [dir:"test" "" "RELATIVE"] = alle files in de relatieve dir op de server, zonder subdirs
 * [dir:"test" "1" "1"] OF [dir:"test" "FULL" "RELATIVE"] = alle files in de relatieve dir op de server, MET subdirs
 * Created on January 21, 2013, 11:36 PM
 */

#include "DirCommand.h"
#include "Config.h"

DirCommand DirCommand::cInstance("DIR");

DirCommand::DirCommand(const char* szID )
	: Command( szID )
{
}

DirCommand::DirCommand() : Command() {
    setName("DIR");
}

DirCommand::~DirCommand() {
}

Command* DirCommand::createNew()
{
    DirCommand * cmd = new DirCommand();
    cmd->setName("DIR");
    return cmd;
}

bool DirCommand::isValid()
{
    return ((getName().compare("DIR") == 0) && (sizeParameters() > 0) && Command::isValid());
}

//hier ontvangt de server het commando van de client
void DirCommand::ExcecuteServerReceiveCommand(TcpSocket* dasServer, queue<Command *>& commandQueue)
{
    cout << getName() << " COMMAND RECEIVED!" << endl;
    dasLog << getName() << " COMMAND RECEIVED!" << endl;
}

//hier komt de server nadat hij een bericht van de client heeft ontvangen met een dir request
//hij moet dus wat terug gaan sturen, hij past dus het huidigge commando aan en stuurt die op
void DirCommand::ExcecuteServerSendCommand(TcpSocket* dasServer, queue<Command *>& commandQueue)
{
    //moet minimaal 1 parameter zijn, de directory waar we files en folders van gaan ophalen
    if(sizeParameters() > 0){ 
        
        string basePath;
        //string pathSEP = Config::getInstance()->PathSeparator;
        string folderPath;
        string doRelativeOrRootPath;
        string doRecursiveGetPath;
        string doSendTimestampLastEdited;
        bool doTimeStamped = false;
        Config::getInstance()->getFullBasePath(basePath);
        
        getParameterAtIndex(0,folderPath);
        getParameterAtIndex(1,doRelativeOrRootPath);
        getParameterAtIndex(2,doRecursiveGetPath);
        getParameterAtIndex(3,doSendTimestampLastEdited);
        
        Utility::getInstance()->fixPathLinuxWindowsProblem(folderPath, true);
        //als de 3e parameter RELATIVE is, dan moet het relatief gezien worden vanaf de server
        if( (doRelativeOrRootPath.compare("RELATIVE") == 0) || (doRelativeOrRootPath.compare("1") == 0) ){
            stringstream ss;
            ss << basePath << folderPath;
            folderPath = ss.str();
        }
        
        if( (doSendTimestampLastEdited.compare("STAMP") == 0) || (doSendTimestampLastEdited.compare("1") == 0) ){
            doTimeStamped = true;
        }
        if(Utility::getInstance()->directoryExists(folderPath)){
            vector<string> filesInDir;
            if((doRecursiveGetPath.compare("FULL") == 0) || (doRecursiveGetPath.compare("1") == 0)){
                Utility::getInstance()->getFilesInDirIncludingSubdirs(folderPath,filesInDir, doTimeStamped);
            } else {
                Utility::getInstance()->getFilesFoldersInDir(folderPath,filesInDir, doTimeStamped);
            }
            
            
            clearParameters(); //wist de huidigge parameters
            
            //als er wel bestanden in de directory staan
            if(filesInDir.size() > 0){
                addParameter(Config::getInstance()->OkRepresenter);
                for(int i = 0; i < filesInDir.size(); i++){
                    addParameter(filesInDir[i]);
                }
            } else { //isleeg
                addParameter(Config::getInstance()->EmptyXMLNodeRepresenter);
            }
        } else {
            //folder not exists
            addParameter(Config::getInstance()->NotExistsRepresenter);
        }
    } else {
        // 0 parameters
        setName("ERROR");
        addParameter("ERROR DIR - ERROR in DirCommand.cpp - ExcecuteServerSendCommand(), failled on: if(sizeParameters() > 0){  - should not ever happen! 88887");
        cout << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', failled on: if(sizeParameters() > 0){  - should not ever happen! 88887" << endl;
        dasLog << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', failled on: if(sizeParameters() > 0){  - should not ever happen! 88887" << endl;
    }
    
    setType("END");
    
    //checkt of het command valide is
    if(!isValid()){
        clearParameters();
        stringstream ssERROR;
        ssERROR << "ERROR 3007 - ERROR BUILDING FULL COMMAND - NOT VALID: ";
        ssERROR << "name: '" << getName()  << "', ";
        ssERROR << "sender: '" << getSender()  << "', ";
        ssERROR << "type: '" << getType()  << "', ";
        addParameter(ssERROR.str());
        //bouwt eerst de error message en past daarna pas de message aan!
        setName("ERROR");
    }
    string totalCommandStr = buildFullCommand();
    if(totalCommandStr.size() > 10){
        dasServer->sendMessage(totalCommandStr);
        cout << "Server send successfully '" << getName() << "' message to client!" << endl;
        dasLog << "Server send successfully '" << getName() << "' message to client!" << endl;
    } else {
        cout << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', failled on: if(totalCommandStr.size() > 10){ - should not ever happen! 88888" << endl;
        dasLog << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', failled on: if(totalCommandStr.size() > 10){ - should not ever happen! 88888" << endl;
    }
}


//dit wordt uitgevoerd als de client het naar de server HEEFT VERSTUURD 
//en gaat wachten op een antwoord!
void DirCommand::ExcecuteClientReceiveCommand(TcpSocket* dasClient, queue<Command *>& commandQueue)
{
    if(!(getName().compare("ERROR") == 0) ){ //als het geen error is
        //haalt het volgende bericht op!
        Command * receivedCMD = getNextCommandFromSocket(dasClient);
        if(receivedCMD != 0){
            //als het GEEN error is
            if( !(receivedCMD->getName().compare("ERROR") == 0) ){ //als het geen error is
                //als het commando gelijk is aan het huidige commando!
                if(receivedCMD->getName().compare(getName()) == 0){
                    if(receivedCMD->sizeParameters() > 0){ 
                        cout << "****START " << receivedCMD->getName() << " COMMAND RECEIVING FILES****" << endl;
                        dasLog << "****START " << receivedCMD->getName() <<" COMMAND RECEIVING FILES****" << endl;
                        //de eerste parameter is de aanduiding of alles goed gegaan is!
                        for(int i = 0; i < receivedCMD->sizeParameters(); i++){
                            string file;
                            receivedCMD->getParameterAtIndex(i,file);
                            cout << " * " << file << endl;
                            dasLog << " * " << file << endl;
                        }

                        //geeft de output terug
                        if(Clone(receivedCMD)){

                        }
                        cout << "****END " << receivedCMD->getName() << " COMMAND RECEIVING FILES****" << endl;
                        dasLog << "****END " << receivedCMD->getName() << " COMMAND RECEIVING FILES****" << endl;
                    } else {
                        cout << getName() << " COMMAND FAILLED!!" << endl;
                        dasLog << getName() << " COMMAND FAILLED!!" << endl;
                        receivedCMD->PrintFullCout(); //debug!
                    }
                } else{
                    cout << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', curr cmd: '" << getName() << "', received cmd: '" << receivedCMD->getName() << "' - should not ever happen! 88886" << endl;
                    dasLog << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', curr cmd: '" << getName() << "', received cmd: '" << receivedCMD->getName() << "' - should not ever happen! 88886" << endl;
                }
            } else { //error
                stringstream ssERROR;
                for(int i = 0; i < receivedCMD->sizeParameters(); i++){
                    string strErr;
                    receivedCMD->getParameterAtIndex(0,strErr);
                    ssERROR << strErr << " - ";
                }
                string strTotalErr = ssERROR.str();
                cout << getName() << " COMMAND FAILLED! received error: " << strTotalErr << endl;
                dasLog << getName() << " COMMAND FAILLED! received error: " << strTotalErr << endl;
            }
        }

        receivedCMD = 0;
        delete receivedCMD;
    }
}
//dit wordt uitgevoerd als de client het ingetypte bericht naar de server verstuurd
void DirCommand::ExcecuteClientSendCommand(TcpSocket* dasClient, queue<Command *>& commandQueue)
{
    setType("END");
    //checkt of het command valide is
    if(!isValid()){
        clearParameters();
        stringstream ssERROR;
        ssERROR << "ERROR on sending '" << getName() << "' command to server! Command is nog valid! - ";
        ssERROR << "ERROR 3008 - ERROR BUILDING FULL COMMAND - NOT VALID: ";
        ssERROR << "name: '" << getName()  << "', ";
        ssERROR << "sender: '" << getSender()  << "', ";
        ssERROR << "type: '" << getType()  << "', ";
        cout << ssERROR.str() << endl;
        dasLog << ssERROR.str() << endl;
        
        clearParameters();
        addParameter(ssERROR.str());
        setName("ERROR");
        
        //@TODO huidigge command error van maken, dat komt dan naar voren in de client receive
    } else { //als alles goed is
        string totalCommandStr = buildFullCommand();
        if(totalCommandStr.size() > 10){
            dasClient->sendMessage(totalCommandStr);
        } else {
            stringstream ss;
            ss << "ERROR in '" << __FILE__ << "' - '" << __FUNCTION__  << "()', if(totalCommandStr.size() > 10){ - should not ever happen! 88887" << endl;
            
            cout << ss.str();
            dasLog << ss.str();
            
            addParameter(ss.str());
            setName("ERROR");
        }
    }
}

